﻿/**
* CRL
*/
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CRL;
using CRL.Core;

namespace CRL.Mongo.MongoDBEx
{
    public sealed partial class MongoDBExt
    {



        public override void BeginTran(System.Data.IsolationLevel isolationLevel = System.Data.IsolationLevel.ReadCommitted)
        {
            return;
        }

        public override void RollbackTran()
        {
            return;
        }

        public override void CommitTran()
        {
            return;
        }

        public override void CheckTableCreated(Type type)
        {
            return;
        }


        IMongoCollection<BsonDocument> getCollection(string bson, out string bson2)
        {
            var arry = bson.Split('.');
            if (arry.Length == 1)
            {
                throw new Exception("格式不正确 table.{bson}");
            }
            var tableName = arry[0];
            bson2 = bson.Substring(tableName.Length + 1);
            return _MongoDB.GetCollection<BsonDocument>(tableName);
        }
        public override Dictionary<TKey, TValue> ExecDictionary<TKey, TValue>(string sql)
        {
            var coll = getCollection(sql, out var bson);
            var result = coll.Find(bson).ToList();
            var dic = new Dictionary<TKey, TValue>();
            foreach (var item in result)
            {
                var key = BsonTypeMapper.MapToDotNetValue(item[0]);
                var value = BsonTypeMapper.MapToDotNetValue(item[1]);
                var keyObj = (TKey)(key ?? default);
                if (!dic.ContainsKey(keyObj))
                {
                    dic.Add(keyObj, (TValue)(value ?? default));
                }
            }
            return dic;
        }

        public override List<dynamic> ExecDynamicList(string sql)
        {
            var coll = getCollection(sql, out var bson);
            var result = coll.Find(bson).ToList();
            var list = new List<dynamic>();
            foreach (var item in result)
            {
                dynamic obj = new System.Dynamic.ExpandoObject();
                var dict = obj as IDictionary<string, object>;
                foreach (var f in item)
                {
                    string columnName = f.Name;
                    object value = BsonTypeMapper.MapToDotNetValue(f.Value);
                    dict.Add(columnName, value);
                }
                list.Add(obj);
            }
            return list;
        }

        public override List<T> ExecList<T>(string sql)
        {
            var coll = getCollection(sql, out var bson);
            var result = coll.Find(bson).ToList();
            var list = new List<T>();
            var fields = TypeCache.GetProperties(typeof(T));
            var reflection = ReflectionHelper.GetInfo<T>();
            foreach (var item in result)
            {
                var obj = new T();
                foreach (var f in fields)
                {
                    string columnName = f.Value.MapingName;
                    var columnName1 = columnName;
                    if (columnName1.ToLower() == "id")
                    {
                        columnName1 = "_id";
                    }
                    var value = BsonTypeMapper.MapToDotNetValue(item[columnName1]);
                    var access = reflection.GetAccessor(columnName);
                    access.Set(obj, value);
                }
                list.Add(obj);
            }
            return list;
        }


        public override T ExecObject<T>(string sql)
        {
            var list = ExecList<T>(sql);
            if (list.Count == 0)
                return null;
            return list[0];
        }

        public override object ExecScalar(string sql)
        {
            throw new NotSupportedException();//不支持
        }

        public override T ExecScalar<T>(string sql)
        {
            throw new NotSupportedException();//不支持
        }

        public override int Execute(string sql)
        {
            throw new NotSupportedException();//不支持
        }

        public override int Run(string sp)
        {
            throw new NotSupportedException();//不支持
        }

        public override List<dynamic> RunDynamicList(string sp)
        {
            throw new NotSupportedException();//不支持
        }

        public override List<T> RunList<T>(string sp)
        {
            throw new NotSupportedException();//不支持
        }

        public override T RunObject<T>(string sp)
        {
            throw new NotSupportedException();//不支持
        }

        public override object RunScalar(string sp)
        {
            throw new NotSupportedException();//不支持
        }
    }
}
